package com.managertrade.config.handler;

import com.managertrade.util.JwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;

@Slf4j
@Component
public class CommandWebSocketHandler extends TextWebSocketHandler {

    private static final List<String> ALLOWED = Arrays.asList(
            "git pull",
            "mvn clean package",
            "systemctl restart"
    );

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) {
        String token = (String) session.getAttributes().get("token");
        String command = message.getPayload();



        // 校验 token
        Claims claims = JwtUtil.parseToken(token);
        String userId = claims.get("userId").toString();
        try {
            log.info("收到 WebSocket 消息: token={}, 命令={}", token, command);
            if (JwtUtil.isTokenExpired(token)) {
                sendMessage(session, "❌ Token 已过期");
                session.close();
                return;
            }
        } catch (Exception e) {
            sendMessage(session, "❌ Token 无效");
            return;
        }

        // 执行命令
        new Thread(() -> executeCommand(session,userId, command)).start();
    }

    private void executeCommand(WebSocketSession session, String userId, String command) {
        log.info("开始执行命令: 用户={}, 命令={}", userId, command);

       /* if (!isAllowed(command)) {
            sendMessage(session, "❌ 非法命令");
            log.warn("用户 {} 尝试执行非法命令: {}", userId, command);
            return;
        }*/

        try {

            String os = System.getProperty("os.name").toLowerCase();
            ProcessBuilder builder;
            if (os.contains("win")) {
                // Windows
                builder = new ProcessBuilder("cmd", "/c", command);
            } else {
                // Linux / Mac
                builder = new ProcessBuilder("bash", "-c", command);
            }
            builder.redirectErrorStream(true);
            Process process = builder.start();

            BufferedReader reader;
            if (os.contains("win")) {
                reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"));
            } else {
                reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
            }
            String line;
            while ((line = reader.readLine()) != null) {
                sendMessage(session, line);
                log.info("命令输出: {}", line);
            }

            int exitCode = process.waitFor();
            sendMessage(session, "✅ 命令执行完成，退出码: " + exitCode);
            log.info("命令执行完成: 用户={}, 命令={}, 退出码={}", userId, command, exitCode);

        } catch (Exception e) {
            sendMessage(session, "❌ 执行异常：" + e.getMessage());
            log.error("执行命令异常: 用户={}, 命令={}, 错误={}", userId, command, e.getMessage(), e);
        }
    }

    private void sendMessage(WebSocketSession session, String msg) {
        try {
            session.sendMessage(new TextMessage(msg + "\n"));
        } catch (Exception e) {
            log.error("发送 WebSocket 消息失败: {}", e.getMessage(), e);
        }
    }

    public static boolean isAllowed(String cmd) {
        return ALLOWED.stream().anyMatch(cmd::startsWith);
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        // 获取 token 参数
        String token = session.getUri().getQuery().replaceFirst("token=", "");
        session.getAttributes().put("token", token); // 保存到 session
        log.info("WebSocket 建立连接, token={}", token);
    }
}
